<template>
    <!-- 正常播放界面 -->
    <AudioPlayer ref="player" :option="{
        src: plays.path, title: plays.name, coverImage: plays.img,
    }" @loadedmetadata="loadedmetadata" @ended="onAudioEnded" />
    <List v-if="listdata && listdata.length > 0" :style="{ padding: '10px 0px 10px 20px' }"
        :grid="{ gutter: 16, xs: 1, sm: 2, md: 4, lg: 4, xl: 6, xxl: 9 }" :data-source="listdata">
        <template #renderItem="{ item }">
            <Dropdown :trigger="['contextmenu']">
                <ListItem>
                    <a v-on:click="getMusicList(item)">
                        <Tag v-text="item.name + '/' + item.num" color="blue" class="mb-2"></Tag>
                    </a>
                </ListItem>
                <template #overlay>
                    <Menu>
                        <MenuItem key="1" @click="editMusicListClick(item)">修改</MenuItem>
                        <Popconfirm title="确定删除?" ok-text="确定" cancel-text="取消" @confirm="delMusicList(item)">
                            <MenuItem key="2">删除</MenuItem>
                        </Popconfirm>
                    </Menu>
                </template>
            </Dropdown>
        </template>
    </List>
    <Row justify="space-between" :style="{ marginTop: '1px', verticalAlign: 'bottom', display: 'flex' }">
        <Col>
        <Input v-model:value="params.selname" placeholder="名称" :style="{ width: '300px', margin: '0 18px' }"></Input>
        <Tooltip title="上传音乐" color="blue">
            <Upload :multiple="true" :show-upload-list="false" :before-upload="handleBeforeUpload"
                class="upload-list-inline">
                <Button style="margin: 0 8px" shape="circle" :icon="h(UploadOutlined)"></Button>
            </Upload>
        </Tooltip>
        <Tooltip title="添加播放列表" color="blue">
            <Button style="margin: 0 8px" shape="circle" :icon="h(PlusOutlined)" @click="addMusicListClick"></Button>
        </Tooltip>
        <Tooltip title="查询名称" color="blue">
            <Button style="margin: 0 8px" shape="circle" :icon="h(SearchOutlined)" @click="selmusicbyname"></Button>
        </Tooltip>
        <Tooltip title="清空" color="blue">
            <Button style="margin: 0 8px" shape="circle" :icon="h(ClearOutlined)" @click="clearname"></Button>
        </Tooltip>
        </Col>
        <Col>
        <Button style="margin-right: 10px;" @click="lastmusic">上一首</Button>
        <Button style="margin-right: 10px;" @click="nextmusic">下一首</Button>
        <Button style="margin-right: 10px;" @click="allmusic">所有音乐</Button>
        <Button style="margin-right: 10px;" @click="nousemusic">闲置音乐</Button>
        <Button style="margin-right: 10px;" @click="switchmode">{{ musicmode[musicmodeindex] }}</Button>
        </Col>
    </Row>
    <Table bordered :data-source="tabledata" :columns="columns" style="margin-top: 1px;" :pagination="false">
        <template #bodyCell="{ column, text, record }">
            <template v-if="column.dataIndex === 'operation'">
                <Button style="margin: 0 8px" shape="circle" :icon="h(PlayCircleOutlined)"
                    @click="playmusic(record)"></Button>
                <Divider type="vertical" />
                <template v-if="listorlocal !== 0">
                    <Dropdown :trigger="['click']">
                        <Button style="margin: 0 8px" shape="circle" :icon="h(PlusOutlined)"></Button>
                        <template #overlay>
                            <Menu>
                                <MenuItem v-for="ld in listdata" :key="ld.id" @click="addmusictoList(record, ld)">{{
                                    ld.name
                                }}</MenuItem>
                            </Menu>
                        </template>
                    </Dropdown>
                    <Divider type="vertical" />
                </template>
                <template v-if="listorlocal !== 0">
                    <Popconfirm v-if="tabledata.length" title="确定删除本地文件?" @confirm="delmusic(record)">
                        <Button style="margin: 0 8px" shape="circle" :icon="h(DeleteOutlined)"></Button>
                    </Popconfirm>
                </template>
                <template v-if="listorlocal === 0">
                    <Button style="margin: 0 8px" shape="circle" :icon="h(DeleteOutlined)"
                        @click="delmusicfromList(record)"></Button>
                </template>
            </template>
        </template>
    </Table>
    <Modal @ok="submitMusicList(true)" @cancel="submitMusicList(false)" :title="musicListTitle"
        v-model:open="musiclistmodal">
        <Form>
            <FormItem label="播放列表名称">
                <Input v-model:value="mlparam.name" />
            </FormItem>
        </Form>
    </Modal>
</template>
<script setup lang="ts">
import AudioPlayer from 'vue3-audio-player'
import 'vue3-audio-player/dist/style.css'
import { ref, onBeforeMount, h } from "vue";
import { post, upload, posturl } from "../util/MyAxios";
import {
    Table,
    Input,
    Popconfirm,
    Button,
    message,
    Divider,
    Row,
    Col,
    Tooltip,
    Upload,
    Tag,
    MenuItem,
    Menu,
    List,
    Dropdown,
    ListItem,
    Modal,
    Form,
    FormItem,
} from "ant-design-vue";
import {
    SearchOutlined,
    ClearOutlined,
    UploadOutlined,
    PlayCircleOutlined,
    DeleteOutlined,
    PlusOutlined,
} from "@ant-design/icons-vue";
import { Api } from '../util/Api';
import { showMessage } from "../util/Mes";

const player = ref(null);
const tabledata = ref<any>();
const listdata = ref<any>();
const musicmode = ref(['列表循环', '单曲循环', '随机播放', '不循环']);
const loadindex = ref(0);//当前音乐在播放列表中的序号
const musicmodeindex = ref(0);//播放模式 列表中的序号
const musiclistmodal = ref<boolean>(false);
const listorlocal = ref<number>(0);//0:list、1:local、2:nouse
const musicListTitle = ref('');

const params = ref({
    path: "",
    name: "",
    oldname: "",
    newname: "",
    selname: "",
});

const mlparam = ref({
    name: "",
    id: 0,
});

const molparam = ref({
    name: "",
    mlid: 0,
    author: "",
    totalseconds: "",
    length: "",
    id: 0,
});

const plays = ref({
    path: "",
    name: "",
    img: "",
});

const columns = [
    {
        title: "名称",
        dataIndex: "name",
        key: "name",
        width: "35%",
    },
    {
        title: "艺术家",
        dataIndex: "author",
        key: "author",
        width: "20%",
    },
    {
        title: "时长",
        dataIndex: "totalseconds",
        key: "totalseconds",
        width: "15%",
    },
    {
        title: "大小",
        dataIndex: "length",
        key: "length",
        width: "15%",
    },
    {
        title: "操作",
        dataIndex: "operation",
        key: "operation",
        width: "15%",
    },
];
//清空查询条件
const clearname = () => {
    params.value.selname = "";
};
//查看所有本地音乐
function allmusic() {
    listorlocal.value = 1;
    fetchData();
}
function nousemusic() {
    listorlocal.value = 2;
    fetchNoUseData();
}
//添加一个播放列表
function addMusicListClick() {
    musicListTitle.value = "添加播放列表";
    mlparam.value.id = 0;
    mlparam.value.name = '';
    musiclistmodal.value = true;
}
function submitMusicList(b) {
    if (b) {
        if (mlparam.value.id === 0) {//添加
            mlparam.value.name = mlparam.value.name;
            addMusicListPost();
        } else {//修改
            mlparam.value.name = mlparam.value.name;
            editMusicListPost();
        }
    }
    musiclistmodal.value = false;
    fetchListData();
}
//修改播放列表名称
async function editMusicListPost() {
    await post(Api.MusicList_EditMusicList, mlparam.value)
        .then((response) => {
            showMessage(response.data, "修改播放列表名称");
            fetchListData();
        })
        .catch((error) => {
            console.error(error);
        });
}
//添加播放列表名称
async function addMusicListPost() {
    await post(Api.MusicList_AddMusicList, mlparam.value)
        .then((response) => {
            showMessage(response.data, "添加播放列表名称");
            fetchListData();
        })
        .catch((error) => {
            console.error(error);
        });
}
//修改播放列表
function editMusicListClick(item) {
    mlparam.value.name = item.name;
    mlparam.value.id = item.id;
    musicListTitle.value = "修改播放列表";
    musiclistmodal.value = true;
}
//删除播放列表
async function delMusicList(item) {
    mlparam.value.id = item.id;
    await post(Api.MusicList_DelMusicList, mlparam.value)
        .then((response) => {
            showMessage(response.data, "删除播放列表");
            fetchListData();
        })
        .catch((error) => {
            console.error(error);
        });
}
//添加音乐到音乐播放列表
async function addmusictoList(record, ld) {
    molparam.value.mlid = ld.id;
    molparam.value.name = record.name;
    molparam.value.author = record.author;
    molparam.value.totalseconds = record.totalseconds;
    molparam.value.length = record.length;
    await post(Api.MusicOfList_AddMusicOfList, molparam.value)
        .then((response) => {
            showMessage(response.data, "添加音乐到播放列表");
            fetchListData();
            if (listorlocal.value === 2) {
                nousemusic();
            }
        })
        .catch((error) => {
            console.error(error);
        });
}

//删除音乐从音乐播放列表
async function delmusicfromList(record) {
    molparam.value.id = record.id;
    await post(Api.MusicOfList_DelMusicOfList, molparam.value)
        .then((response) => {
            showMessage(response.data, "删除音乐从播放列表");
            fetchListData();
            mlparam.value.id = record.mlid;
            getMusicList(mlparam.value);
        })
        .catch((error) => {
            console.error(error);
        });
}
//删除本地音乐
async function delmusic(record) {
    params.value.name = record.name;
    await post(Api.Music_DelMusic, params.value)
        .then((response) => {
            showMessage(response.data, "删除本地音乐");
            allmusic();
        })
        .catch((error) => {
            console.error(error);
        });
}

//上传音乐文件
const handleBeforeUpload = (file) => {
    const formData = new FormData();
    formData.append("file", file);
    if (params.value.path) {
        formData.append("fileurl", params.value.path);
    }
    return upload(Api.Music_UploadMusic, formData, {
        headers: {
            "Content-Type": "multipart/form-data",
        },
    })
        .then((response) => {
            message.info("已上传:" + response.data);
            allmusic();
            return false;
        })
        .catch((error) => {
            console.error(error);
            return false;
        });
};

//刷新表格数据
async function fetchData() {
    await post(Api.Music_GetMusicPathInfo, params.value)
        .then((response) => {
            if (response.data && response.data.rows.length > 0) {
                for (let i = 0; i < response.data.rows.length; i++) {
                    response.data.rows[i].length = getSize(response.data.rows[i].length);
                    response.data.rows[i].totalseconds = getTimeSize(response.data.rows[i].totalseconds);
                }
            }
            tabledata.value = response.data.rows;
        })
        .catch((error) => {
            console.error(error);
        });
}
//获取还没有配置到播放列表的音乐
async function fetchNoUseData() {
    await post(Api.Music_GetNoUseMusic, params.value)
        .then((response) => {
            if (response.data && response.data.rows.length > 0) {
                for (let i = 0; i < response.data.rows.length; i++) {
                    response.data.rows[i].length = getSize(response.data.rows[i].length);
                    response.data.rows[i].totalseconds = getTimeSize(response.data.rows[i].totalseconds);
                }
            }
            tabledata.value = response.data.rows;
        })
        .catch((error) => {
            console.error(error);
        });
}

//刷新播放列表数据
async function fetchListData() {
    await posturl(Api.MusicOfList_GetMusicOfList)
        .then((response) => {
            listdata.value = response.data;
        })
        .catch((error) => {
            console.error(error);
        });
}
//转到播放列表内容
async function getMusicList(item) {
    listorlocal.value = 0;
    await post(Api.MusicOfList_GetMusicOfListBymlid, item)
        .then((response) => {
            tabledata.value = response.data;
        })
        .catch((error) => {
            console.error(error);
        });
}
//查询音乐通过名称
async function selmusicbyname() {
    if (params.value.selname && params.value.selname.length > 0) {
        await post(Api.Music_SelMusicByName, params.value)
            .then((response) => {
                if (response.data && response.data.rows && response.data.rows.length > 0) {
                    for (let i = 0; i < response.data.rows.length; i++) {
                        response.data.rows[i].length = getSize(response.data.rows[i].length);
                        response.data.rows[i].totalseconds = getTimeSize(response.data.rows[i].totalseconds);
                    }
                }
                tabledata.value = response.data;
            })
            .catch((error) => {
                console.error(error);
            });
    } else {
        allmusic();
    }
}

//页面初加载 有播放列表加载第一个播放列表,没有播放列表，加载所有本地音乐
onBeforeMount(() => {
    posturl(Api.MusicOfList_GetMusicOfList)
        .then((response) => {
            listdata.value = response.data;
            if (listdata.value && listdata.value.length > 0) {
                mlparam.value.id = listdata.value[0].id;
                getMusicList(mlparam.value);
            } else {
                allmusic();
            }
        })
        .catch((error) => {
            console.error(error);
            allmusic();
        });
});

//文件大小格式转换
function getSize(length) {
    if (length === 0) return "0 B";

    const units = ["B", "KB", "MB", "GB", "TB"];
    let index = Math.floor(Math.log(length) / Math.log(1024));
    if (index > units.length - 1) index = units.length - 1;

    const convertedSize = length / Math.pow(1024, index);
    return convertedSize.toFixed(2) + " " + units[index];
}

//文件时长格式转换
function getTimeSize(length) {
    if (length === 0) return "0 s";

    const units = ["s", "min", "hour"];
    let index = Math.floor(Math.log(length) / Math.log(60));
    if (index > units.length - 1) index = units.length - 1;

    const convertedSize = length / Math.pow(60, index);
    return convertedSize.toFixed(2) + " " + units[index];
}

//音乐播放结束
const onAudioEnded = () => {
    nextmusic();
};
//加载音乐资源
const loadedmetadata = () => {
    player.value.play();
};

//播放音乐
function playmusic(record) {
    plays.value.name = record.name;
    plays.value.path = record.path;
    plays.value.img = record.thumbnail;
    loadindex.value = record.index;
}
//上一首
function lastmusic() {
    if (tabledata.value.length > 0) {
        if (loadindex.value === 0) {
            loadindex.value = tabledata.value.length - 1;
        } else {
            loadindex.value--;
        }
        plays.value.name = tabledata.value[loadindex.value].name;
        plays.value.path = tabledata.value[loadindex.value].path;
        plays.value.img = tabledata.value[loadindex.value].thumbnail;
    }
}
//下一首
function nextmusic() {
    if (tabledata.value.length > 0 && musicmodeindex.value !== 3) {
        if (musicmodeindex.value === 0) {//列表循环
            if (loadindex.value === tabledata.value.length - 1) {
                loadindex.value = 0;
            } else {
                loadindex.value++;
            }
        }
        if (musicmodeindex.value === 2) {//随机播放
            loadindex.value = getRandomInt(0, tabledata.value.length - 1);
        }
        plays.value.name = tabledata.value[loadindex.value].name;
        plays.value.path = tabledata.value[loadindex.value].path;
        plays.value.img = tabledata.value[loadindex.value].thumbnail;
        if (musicmodeindex.value === 1) {//单曲循环
            loadedmetadata();
        }
    }
}
//切换播放模式
function switchmode() {
    musicmodeindex.value++;
    if (musicmodeindex.value >= musicmode.value.length) {
        musicmodeindex.value = 0;
    }
}
//获取随机整数
function getRandomInt(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

</script>
<style scoped>
:deep(.ant-table-tbody > tr > td) {
    height: 10px;
    padding: 5px;
}

:deep(.ant-table-thead > tr > th) {
    height: 10px;
    padding: 9px;
}

.background-red {
    background-color: red;
}
</style>